package br.com.tiespec.web.ManagedBean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;

import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.primefaces.model.mindmap.DefaultMindmapNode;
import org.primefaces.model.mindmap.MindmapNode;

import br.com.tiespec.ejb.EjbInterface.DescricaoEstendidaInterface;
import br.com.tiespec.model.Enum.TipoPrioridade;
import br.com.tiespec.model.Enum.TipoRisco;
import br.com.tiespec.model.Enum.TipoSortOrder;
import br.com.tiespec.model.Modelo.Ator;
import br.com.tiespec.model.Modelo.Cenario;
import br.com.tiespec.model.Modelo.CenarioBase;
import br.com.tiespec.model.Modelo.Dado;
import br.com.tiespec.model.Modelo.DescricaoEstendida;
import br.com.tiespec.model.Modelo.Projeto;
import br.com.tiespec.web.Util.InitUtil;
import br.com.tiespec.web.Util.MsgUtil;
import br.com.tiespec.web.Util.WebUtil;

@Named("deBean")
@SessionScoped
public class DescricaoEstendidaBean implements Serializable {

	private static final long serialVersionUID = -7778863626034900205L;

	@EJB private DescricaoEstendidaInterface ejb;
	@Inject private ContextoBean contexto;
	
	private DescricaoEstendida deInstance;
	private DescricaoEstendida deInstanceTemp;
	
	private List<Ator> atorList;
	
	private LazyDataModel<DescricaoEstendida > deList;
	private String varCodigo;
	private String varNome;
	private String varProjeto;
	private Long idClientePortal;
	
	private Dado dadoInstance;
	private Cenario cenarioInstance;
	
	private CenarioBase cBaseInstance;
	
	private LazyDataModel<CenarioBase> cBaseList;
	private LazyDataModel<Cenario> cenarioList;
	private LazyDataModel<Dado> dadoList;
	private Dado[] dadosSelecionados;
	
	
	private MindmapNode root;
	private MindmapNode selectedNode;
	
	private void montarMindMap(){
		
		Projeto pInstance = contexto.getProjetoEmContexto();
		
		root = new DefaultMindmapNode(pInstance.getCodigo(), pInstance.getNome(), "0000FF", false);  
		
		//Listo todas descrições estendidas e faço um mind map para cada uma
		List<DescricaoEstendida> descList = ejb.listarDescricaoEstendidas(pInstance.getId());
		MindmapNode mmn;
		MindmapNode mmnTemp;
		for (DescricaoEstendida de:descList){
			mmn = new DefaultMindmapNode(de.getCodigo(), de.getNome(), "0033FF", true);  
			List<Cenario> cenariosList = ejb.listarCenarios(de.getId());
			for (Cenario c:cenariosList){
				mmnTemp = new DefaultMindmapNode(c.getNome(), c.getNome(), "0066FF", true);
				mmn.addNode(mmnTemp);
			}
			root.addNode(mmn);
		}
	}
	
	public void onNodeSelect(SelectEvent event){
		 this.selectedNode = (MindmapNode) event.getObject();
	}
	
	private String atoresSelecionados;
	
	public List<String> onCompleteAtores(String query) {  
		List<String> result = new ArrayList<String>();
		for (Ator a:ejb.listarAtores(idClientePortal, query)){
			result.add(a.getNome());
		}
        return result;  
    }  
	
	private String msgExclusao;
	
	public String descricaoEstendida(){
		init();
		montarMindMap();
		return "/views/de/show.xhtml";
	}
	
	@PostConstruct
	public void init(){
		deInstance = new DescricaoEstendida();
		deInstance.setProjeto(new Projeto());
		deInstanceTemp = new DescricaoEstendida();
		deList = InitUtil.inicializaDescricaoEstendidaList();
		cBaseList = InitUtil.inicializaCenarioBaseList();
		idClientePortal = WebUtil.getClientePortalEmContexto().getId();
		dadoInstance = new Dado();
	}
	
	public String goCreate(){
		deInstance = new DescricaoEstendida();
		deInstance.setProjeto(contexto.getProjetoEmContexto());
		deInstance.setAtores(new ArrayList<Ator>());
		deInstance.setCenarios(new ArrayList<Cenario>());
		deInstance.setRisco(TipoRisco.MEDIO);
		deInstance.setPrioridade(TipoPrioridade.MEDIA);
		return "/views/de/create.xhtml";
	}
	
	public String salvarDE(){
		try {
			tratamentoAtores();
			ejb.salvarDescricaoEstendida(deInstance);
			MsgUtil.msgSucesso("inc", deInstance.getCodigo());
			return "/views/de/show.xhtml";
		} catch (Exception e){
			e.printStackTrace();
			MsgUtil.msgErro("inc", deInstance.getCodigo());
			return null;
		}
	}
	
	public String desistirCreate(){
		deInstance = new DescricaoEstendida();
		return "/views/de/show.xhtml";
	}
	
	private void tratamentoAtores(){
		if (atoresSelecionados != null){
			atoresSelecionados = atoresSelecionados.substring(1, atoresSelecionados.length()-1);
			String[] strArray = atoresSelecionados.split(","); 
			List<Ator> aList = ejb.listarAtores(idClientePortal, strArray);
			deInstance.setAtores(aList);
		}
	}
	
	public String goEdit(){
		atoresSelecionados = deInstance.getAtoresTexto();
		return "/views/de/edit.xhtml";
	}
	
	public String atualizarDE(){
		try {
			tratamentoAtores();
			ejb.atualizarDescricaoEstendida(deInstance);
			MsgUtil.msgSucesso("atu", deInstance.getCodigo());
			return "/views/de/show.xhtml";
		} catch (Exception e){
			e.printStackTrace();
			MsgUtil.msgErro("atu", deInstance.getCodigo());
			return null;
		}
	}
	
	@SuppressWarnings("serial")
	public void buscarDescricao(){
		deList = new LazyDataModel<DescricaoEstendida>() {
			@Override
			public List<DescricaoEstendida> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
				WebUtil.setDataTableRows(pageSize);
				return ejb.listarDescricaoEstendidas(first, pageSize, sortField, 
					TipoSortOrder.convertePrimeFaces(sortOrder.toString()), idClientePortal, varCodigo, varNome, varProjeto);
			}
			@Override  
	        public DescricaoEstendida getRowData(String rowKey) {  
	        	try {
		            return ejb.selecionarDescricao(Long.parseLong(rowKey));
	        	} catch (NumberFormatException e){
	        		return new DescricaoEstendida();
	        	}
	        }  
	        @Override  
	        public String getRowKey(DescricaoEstendida objeto)  
	        {  
	        	if (objeto!=null)
	        		return ""+objeto.getId();
	        	return "";
	        }  
		};
		deList.setRowCount(ejb.countDescricaoEstendidas(idClientePortal, varCodigo, varNome, varProjeto));
		deList.setPageSize(5);
	}
	
	public void selecionarDescricao(){
		if (deInstanceTemp != null){
			deInstance = ejb.selecionarDescricaoCompleta(deInstanceTemp.getId());
			deInstance.setAtores(ejb.listarAtores(deInstance.getId()));
		}
		cancelarSelecionarDescricao();
	}
	
	public void cancelarSelecionarDescricao(){
		deList = InitUtil.inicializaDescricaoEstendidaList();
		varCodigo = null;
		varProjeto = null;
		varNome = null;
	}
	
	public void preNovoDado(){
		dadoInstance = new Dado();
	}
	
	public void salvarDado(){
		try {
			dadoInstance.setDescricaoEstendida(deInstance);
			ejb.salvarDado(dadoInstance);
			MsgUtil.msgSucesso("sal", dadoInstance.getNomeTela());
		} catch (Exception e){
			MsgUtil.msgErro("sal", dadoInstance.getNomeTela());
			e.printStackTrace();
		}
		listarDados();
	}
	
	public void preEditarDado(Long id){
		dadoInstance = ejb.selecionarDado(id);
	}
	
	public void atualizarDado(){
		try {
			dadoInstance.setDescricaoEstendida(deInstance);
			ejb.atualizarDado(dadoInstance);
			MsgUtil.msgSucesso("atu", dadoInstance.getNomeTela());
		} catch (Exception e){
			MsgUtil.msgErro("atu", dadoInstance.getNomeTela());
			e.printStackTrace();
		}
		listarDados();
	}
	
	public void preExcluirDado(){
		RequestContext contexto = RequestContext.getCurrentInstance();
		Integer size = dadosSelecionados.length;
		if (size == 0){
			contexto.execute("dialogoSelecione.show();");
			return;
		}
		if (size == 1){
			for (Dado d: dadosSelecionados){
				msgExclusao = MsgUtil.getMensagem("DialogoExcluir_MensagemUnico", d.getNomeTela());
			}
		} else {
			String msg = "";
			Integer count = 0;
			for (Dado d: dadosSelecionados){
				msg += "'" + d.getNomeTela() + "'";
				count++;
				if (count==(size-1))
					msg += " e ";
				else if (count != size)
					msg += ", ";
			}
			msgExclusao = MsgUtil.getMensagem("DialogoExcluir_MensagemMultiplo", msg);
		}
		contexto.execute("dialogoExcluir.show();");
	}
	
	public void excluirDado(){
		for (Dado d:dadosSelecionados){
			try {
				ejb.excluirDado(d);
				MsgUtil.msgSucesso("exc", d.getNomeTela());
			} catch (Exception e){
				MsgUtil.msgErro("exc", d.getNomeTela());
				e.printStackTrace();
			}
		}
		listarDados();
	}
	
	@SuppressWarnings("serial")
	public void listarDados(){
		dadoList = new LazyDataModel<Dado>() {
			@Override
			public List<Dado> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
				WebUtil.setDataTableRows(pageSize);
				return ejb.listarDados(first, pageSize, sortField, 
					TipoSortOrder.convertePrimeFaces(sortOrder.toString()), deInstance.getId());
			}
			@Override  
	        public Dado getRowData(String rowKey) {  
	        	try {
		            return ejb.selecionarDado(Long.parseLong(rowKey));
	        	} catch (NumberFormatException e){
	        		return new Dado();
	        	}
	        }  
	        @Override  
	        public String getRowKey(Dado objeto)  
	        {  
	        	if (objeto!=null)
	        		return ""+objeto.getId();
	        	return "";
	        }  
		};
		dadoList.setRowCount(ejb.countDados(deInstance.getId()));
		dadoList.setPageSize(5);
	}
	
	public String goHome(){
		destroy();
		return "goHome";
	}
	
	@PreDestroy
	public void destroy(){
		
	}

	public DescricaoEstendida getDeInstance() {
		return deInstance;
	}

	public void setDeInstance(DescricaoEstendida deInstance) {
		this.deInstance = deInstance;
	}

	public DescricaoEstendida getDeInstanceTemp() {
		return deInstanceTemp;
	}

	public void setDeInstanceTemp(DescricaoEstendida deInstanceTemp) {
		this.deInstanceTemp = deInstanceTemp;
	}

	public List<Ator> getAtorList() {
		return atorList;
	}

	public void setAtorList(List<Ator> atorList) {
		this.atorList = atorList;
	}

	public LazyDataModel<DescricaoEstendida> getDeList() {
		return deList;
	}

	public void setDeList(LazyDataModel<DescricaoEstendida> deList) {
		this.deList = deList;
	}

	public Dado getDadoInstance() {
		return dadoInstance;
	}

	public void setDadoInstance(Dado dadoInstance) {
		this.dadoInstance = dadoInstance;
	}

	public Cenario getCenarioInstance() {
		return cenarioInstance;
	}

	public void setCenarioInstance(Cenario cenarioInstance) {
		this.cenarioInstance = cenarioInstance;
	}

	public CenarioBase getcBaseInstance() {
		return cBaseInstance;
	}

	public void setcBaseInstance(CenarioBase cBaseInstance) {
		this.cBaseInstance = cBaseInstance;
	}

	public LazyDataModel<CenarioBase> getcBaseList() {
		return cBaseList;
	}

	public void setcBaseList(LazyDataModel<CenarioBase> cBaseList) {
		this.cBaseList = cBaseList;
	}
	
	public LazyDataModel<Cenario> getCenarioList() {
		return cenarioList;
	}
	
	public void setCenarioList(LazyDataModel<Cenario> cenarioList) {
		this.cenarioList = cenarioList;
	}
	
	public LazyDataModel<Dado> getDadoList() {
		return dadoList;
	}
	
	public void setDadoList(LazyDataModel<Dado> dadoList) {
		this.dadoList = dadoList;
	}
	
	public Dado[] getDadosSelecionados() {
		return dadosSelecionados;
	}
	
	public void setDadosSelecionados(Dado[] dadosSelecionados) {
		this.dadosSelecionados = dadosSelecionados;
	}
	
	public String getMsgExclusao() {
		return msgExclusao;
	}
	
	public void setMsgExclusao(String msgExclusao) {
		this.msgExclusao = msgExclusao;
	}
	
	public String getVarCodigo() {
		return varCodigo;
	}
	
	public void setVarCodigo(String varCodigo) {
		this.varCodigo = varCodigo;
	}
	
	public String getVarNome() {
		return varNome;
	}
	
	public void setVarNome(String varNome) {
		this.varNome = varNome;
	}
	
	public String getVarProjeto() {
		return varProjeto;
	}
	
	public void setVarProjeto(String varProjeto) {
		this.varProjeto = varProjeto;
	}

	public String getAtoresSelecionados() {
		return atoresSelecionados;
	}
	
	public void setAtoresSelecionados(String atoresSelecionados) {
		this.atoresSelecionados = atoresSelecionados;
	}
	
	public MindmapNode getRoot() {
		return root;
	}
	
	public void setRoot(MindmapNode root) {
		this.root = root;
	}
	
	public MindmapNode getSelectedNode() {
		return selectedNode;
	}
	
	public void setSelectedNode(MindmapNode selectedNode) {
		this.selectedNode = selectedNode;
	}
	
}